local t = {actvtStatus=nil}
local t4Player = Class({['isMember?']=true})

local ActvtStatus_Play = 1
local ActvtStatus_GameOver = 2

t.events = {
    MapHookEvent.OnPlayerEnter,
    MapHookEvent.OnPlayerLeave,
    MapHookEvent.OnUnitDead,
}

t4Player.events = {
    ObjectHookEvent.OnPlayerChangeGuild,
}

function main(pMapInstance, pHook)
    t.instance, t.hook = pMapInstance, pHook
    t.handler = pMapInstance:AttachMapHookInfo(t)
    t.vars = pHook:GetVariables()
    t.vars.Play = t.Play
end

function t.Play(startTime, prepareTime, durationTime)
    t.startTime, t.prepareTime, t.durationTime =
        startTime, prepareTime, durationTime
    CreateTimerX(t.hook, function() t.StartFight() end,
        math.max(startTime + prepareTime - unixtime(), 0) * 1000, 1)
end

function t.StartFight()
    local winGuildId = t.hook:TryGetWinGuildId4Opening()
    if winGuildId == -1 then
        t.actvtStatus = ActvtStatus_Play
        t.hook:WatchShutdownMapInstance(5*1000, 0)
        CreateTimerX(t.hook, function() t.ForceGameOver() end,
            math.max(t.startTime + t.durationTime - unixtime(), 0) * 1000, 1)
    else
        t.OnGameOver(winGuildId)
    end
end

function t.ForceGameOver()
    if t.actvtStatus == ActvtStatus_Play then
        t.OnGameOver(t.hook:JudgeWinGuildId())
    end
end

function t.TryGameOver(pPlayer)
    local teamSide = pPlayer:GetTeamSide()
    if teamSide ~= -1 then
        local winGuildId = t.hook:TryGetWinGuildId(teamSide)
        if winGuildId ~= -1 then
            t.OnGameOver(winGuildId)
        end
    end
end

function t.OnGameOver(winGuildId)
    t.SendGameOver(winGuildId)
    t.instance:PlayGameOver()
    t.hook:ShutdownMapInstance(60*1000)
    t.actvtStatus = ActvtStatus_GameOver
end

function t.SendGameOver(winGuildId)
    local buffer = StringBuilder:new()
    buffer:WriteUInt64(t.instance:getInstGuid())
    buffer:WriteUInt32(winGuildId)
    buffer:WriteInt64(t.startTime)
    SendPacket2GS(t.instance:
        getOwnerGsId(), MS_FINISH_GUILD_LEAGUE, buffer:tostr())
end

function t.OnPlayerEnter(pPlayer)
    local teamSide = t.hook:GetTeamSide(pPlayer:GetGuildId())
    if teamSide ~= -1 then
        pPlayer:SetTeamSide(teamSide)
        local vars = pPlayer:GetVariables()
        if not vars['guild.league?'] then
            vars['guild.league?'] = pPlayer:
                AttachObjectHookInfo(t4Player:new({player=pPlayer}))
        end
    else
        t.instance:AddEvent(
            function() t.instance:ForcePlayerLeave(pPlayer) end)
    end
end

function t.OnPlayerLeave(pPlayer)
    if t.actvtStatus == ActvtStatus_Play then
        t.TryGameOver(pPlayer)
    end
end

function t.OnUnitDead(pUnit)
    if t.actvtStatus == ActvtStatus_Play then
        if pUnit:IsType(TYPE_PLAYER) then
            t.TryGameOver(pUnit)
        end
    end
end

function t4Player:OnPlayerChangeGuild(guildId)
    t.instance:ForcePlayerLeave(t.player)
end